// UE4TFunction.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>

/** 声明类模板名：TEnableIf，Result具有默认值void [9/12/2020 ZC] */
template <bool Predicate, typename Result = void>
class TEnableIf;

/** 显示实例化定义，强制实例化class,struct,union,这里指定Predicate = true [9/12/2020 ZC] */
/** Predicate = true,声明了类成员变量 Type [9/12/2020 ZC] */
template <typename Result>
class TEnableIf<true, Result>
{
public:
	/** typedef 名是既存类型的别名，而并非对新类型的声明 [9/12/2020 ZC] */
	/** 在这里是指：Result的别名为Type [9/12/2020 ZC] */
	typedef Result Type;
	/** 这里，使用using也可以，也是Result的别名为Type [9/12/2020 ZC] */
	/** using也可以指代一族类型的名字 [9/12/2020 ZC] */
	//using Type = Result;
};

/**
 * Does a boolean AND of the ::Value static members of each type, but short-circuits if any Type::Value == false.
 */
/** 声明模板名TAnd [9/12/2020 ZC] */
template <typename... Types>
struct TAnd;

/** 隐式实例化TAndValue模板 [9/12/2020 ZC] */
template <bool LHSValue, typename... RHS>
struct TAndValue
{
	/**TAnd<RHS...>::Value将会自动解包  [9/12/2020 ZC] */
	enum { Value = TAnd<RHS...>::Value };
};

/** 显示实例化定义，指定LHSValue = false,并指定枚举Value = false [9/12/2020 ZC] */
template <typename... RHS>
struct TAndValue<false, RHS...>
{
	enum { Value = false };
};

/** 显示特例化TAnd，继承于TAndValue<LHS::Value, RHS...> [9/12/2020 ZC] */
/** 在使用时，TAnd将会自动解包，最终会调用TAnd<> [9/12/2020 ZC] */
template <typename LHS, typename... RHS>
struct TAnd<LHS, RHS...> : TAndValue<LHS::Value, RHS...>
{
};

template <>
struct TAnd<>
{
	enum { Value = true };
};

/** 判断FuncType能否绑定到FunctorType上 [9/12/2020 ZC] */
/** 换句话说，判断TFunction声明的函数FuncType与传进来的函数FunctorType是否匹配 [9/12/2020 ZC] */
template <typename FuncType, typename FunctorType>
struct TFuncCanBindToFunctor;

/** 处理有返回值的函数判定 [9/12/2020 ZC] */
/**
* 在显示实例化中，将FuncType【TFunction中声明的函数类型】重命名为FunctorType
* 并把声明模板名中的FunctorType，拆解成Ret和参数包ParamTypes
* 在TFuncCanBindToFunctor<Ret(ParamTypes...), FunctorType> 中，
* 把声明的 Ret和参数包ParamTypes，重新组合成一个参数Ret(ParamTypes...)，
* 以此来满足TFuncCanBindToFunctor的模板声明
*/
template <typename FunctorType, typename Ret, typename... ParamTypes>
struct TFuncCanBindToFunctor<Ret(ParamTypes...), FunctorType> :
/** TAnd包含的两个条件都为true，表示可以绑定，否则不可以 [9/12/2020 ZC] */
	TAnd<
	/** TIsInvocable判断函数FunctorType是否可以通过参数包调用而不报错，返回true表示不报错，且TFuncCanBindToFunctor可以绑定 [9/12/2020 ZC] */
	TIsInvocable<FunctorType, ParamTypes...>,
	/** 判断返回值的类型是否兼容 [9/12/2020 ZC] */
	TFunctorReturnTypeIsCompatible<FunctorType, Ret, ParamTypes...>
	>
{
};
/** 处理没有返回值的函数判定 [9/12/2020 ZC] */
/**
* 在显示实例化中，将FuncType【TFunction中声明的函数类型】重命名为FunctorType
* 并把声明模板名中的FunctorType，拆解成参数包ParamTypes
* 在TFuncCanBindToFunctor<void(ParamTypes...), FunctorType> 中，
* 把声明的 Ret和参数包ParamTypes，重新组合成一个参数void(ParamTypes...)，
* 以此来满足TFuncCanBindToFunctor的模板声明
*/
template <typename FunctorType, typename... ParamTypes>
struct TFuncCanBindToFunctor<void(ParamTypes...), FunctorType> :
/** TIsInvocable判断函数FunctorType是否可以通过参数包调用而不报错，返回true表示不报错，且TFuncCanBindToFunctor可以绑定 [9/12/2020 ZC] */
	TIsInvocable<FunctorType, ParamTypes...>
{
};

/**
 * Does a boolean NOT of the ::Value static members of the type.
 */
template <typename Type>
struct TNot
{
	enum { Value = !Type::Value };
};

/** 显示实例化定义，强制实例化class,struct,union,这里指定Predicate = false [9/12/2020 ZC] */
/** Predicate = false,没有任何声明，这里能说明为啥TEnableIf第一个参数为false时，编译不过 [9/12/2020 ZC] */
/** 因为没有成员变量 [9/12/2020 ZC] */
template <typename Result>
class TEnableIf<false, Result>
{ };

template <typename FuncType>
class TFunction final : public UE4Function_Private::TFunctionRefBase<UE4Function_Private::TFunctionStorage<false>, FuncType>
{
	using Super = UE4Function_Private::TFunctionRefBase<UE4Function_Private::TFunctionStorage<false>, FuncType>;

public:
	/**
	 * Default constructor.
	 */
	TFunction(TYPE_OF_NULLPTR = nullptr)
	{
	}

	/**
	 * Constructor which binds a TFunction to any function object.
	 * typename = typename TEnableIf<...>::Type这句话，表示对模板参数
	 * FunctorType做了限定，FunctorType这种类型必须满足TAnd<
		TNot<TIsTFunction<typename TDecay<FunctorType>::Type>>,
		UE4Function_Private::TFuncCanBindToFunctor<FuncType, FunctorType>
		>::Value这个条件，当TAnd<...>::Value = false时，将会编译错误，否则，编译通过
	 */
	template <
		typename FunctorType,
		typename = typename TEnableIf<
		TAnd<
		TNot<TIsTFunction<typename TDecay<FunctorType>::Type>>,
			UE4Function_Private::TFuncCanBindToFunctor<FuncType, FunctorType>
		>::Value
		>::Type
	>
		TFunction(FunctorType&& InFunc)
		: Super(Forward<FunctorType>(InFunc))
	{
		// This constructor is disabled for TFunction types so it isn't incorrectly selected as copy/move constructors.

		// This is probably a mistake if you expect TFunction to take a copy of what
		// TFunctionRef is bound to, because that's not possible.
		//
		// If you really intended to bind a TFunction to a TFunctionRef, you can just
		// wrap it in a lambda (and thus it's clear you're just binding to a call to another
		// reference):
		//
		// TFunction<int32(float)> MyFunction = [MyFunctionRef](float F) { return MyFunctionRef(F); };
		static_assert(!TIsTFunctionRef<typename TDecay<FunctorType>::Type>::Value, "Cannot construct a TFunction from a TFunctionRef");
	}
	/** default显示默认化函数定义：令编译器为某个类生成特殊成员函数或比较运算符 (C++20 起)的显式指令 [9/12/2020 ZC] */
	TFunction(TFunction&&) = default;
	TFunction(const TFunction& Other) = default;
	~TFunction() = default;

	/**
	 * Move assignment operator.
	 */
	TFunction& operator=(TFunction&& Other)
	{
		Swap(*this, Other);
		return *this;
	}

	/**
	 * Copy assignment operator.
	 */
	TFunction& operator=(const TFunction& Other)
	{
		TFunction Temp = Other;
		Swap(*this, Temp);
		return *this;
	}

	/**
	 * Tests if the TFunction is callable.
	 */
	FORCEINLINE explicit operator bool() const
	{
		return Super::IsSet();
	}
}; 

int main()
{
    std::cout << "Hello World!\n";
}